import argparse
import re

# 统计字符数
def count_characters(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            text = file.read()
            return len(text)
    
    # 文件不存在
    except Exception as e:
        print("FileNotFoundError", '\n')
    
# 统计单词数
def count_words(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            text = file.read()
            words = re.findall(r'\b\w+\b', text)
            return len(words)
        
    except Exception as e:
        print("FileNotFoundError", '\n')   

# 统计句数
def count_sentences(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            text = file.read()
            sentences = re.split(r'[\.\?\!]\s', text)
            return len(sentences)
        
    except Exception as e:
        print("FileNotFoundError", '\n')

# 统计代码行、空行、注释行
def count_code_lines(file_path):
    try:
        code_lines = 0
        empty_lines = 0
        comment_lines = 0
        with open(file_path, 'r', encoding='utf-8') as file:
            lines = file.readlines()
            for line in lines:
                line = line.strip()
                # 空行
                if line == '':
                    empty_lines += 1

                # 注释行
                elif line.startswith('#'):  # Python注释以#开头
                    # C中头文件以#include开头，防止错计
                    if not line.startswith('#include'):     
                        comment_lines += 1   
                elif line.startswith('//'):  # C++、Java等注释以//开头
                    comment_lines += 1
                elif line.startswith('/*') and line.endswith('*/'):  # C、C++多行注释以/*开头，*/结尾
                    comment_lines += 1
                elif line.startswith('/*'):  # C、C++多行注释以/*开头
                    comment_lines += 1
                    while not line.endswith('*/'):  # 如果没有以*/结尾，则继续读取下一行
                        comment_lines += 1
                        line = file.readline().strip()
                elif line.startswith('<!--') and line.endswith('-->'):  # HTML注释以<!--开头，-->结尾
                    comment_lines += 1

                # 代码行
                else:
                    code_lines += 1
                    
        return code_lines, empty_lines, comment_lines
    
    except Exception as e:
        print("FileNotFoundError", '\n')    

        
def main():
    # 命令行帮助描述
    parser = argparse.ArgumentParser(description='Text and Code Counting Program')
    parser.add_argument('file_path', help='File path')
    parser.add_argument('-c', action='store_true', help='Count characters')
    parser.add_argument('-w', action='store_true', help='Count words')
    parser.add_argument('-s', action='store_true', help='Count sentences')
    parser.add_argument('-d', action='store_true', help='Count code lines') 
    parser.add_argument('-e', action='store_true', help='Count empty lines')
    parser.add_argument('-n', action='store_true', help='Count comment lines')

    args = parser.parse_args()
    
    # 命令行结果输出 
    if args.c:      # -c 字符
        count = count_characters(args.file_path)
        print(f"Characters count: {count}")
    
    if args.w:      # -w 单词
        count = count_words(args.file_path)
        print(f"Word count: {count}")
    
    if args.s:      # -s 句子
        count = count_sentences(args.file_path)
        print(f"Sentence count: {count}")

    if args.d:      # -d 代码行数
        code_lines, empty_lines, comment_lines = count_code_lines(args.file_path)
        print(f"Code lines: {code_lines}")

    if args.e:      # -e 空行数
        code_lines, empty_lines, comment_lines = count_code_lines(args.file_path)
        print(f"Empty lines: {empty_lines}")

    if args.n:      # -n 注释行数
        code_lines, empty_lines, comment_lines = count_code_lines(args.file_path)        
        print(f"Comment lines: {comment_lines}")

    # 验证输入的命令是否合法
    valid_commands = ['-c', '-w', '-s', '-d', '-e', '-n']
    if not any([getattr(args, command[1:]) for command in valid_commands]):
        print("Invalid command! Please input at least one valid command.")
        exit(1)


if __name__ == '__main__':
    main()